<?php

if(!defined('COMMON_DATATABLE_CLASS_NUMBER')) {
    define('COMMON_DATATABLE_CLASS_NUMBER', 'n');
}

if(!defined('COMMON_DATATABLE_CLASS_NEGATIVE')) {
    define('COMMON_DATATABLE_CLASS_NEGATIVE', 'neg');
}

if(!defined('COMMON_DATATABLE_CLASS_IDENTIFIER')) {
    define('COMMON_DATATABLE_CLASS_IDENTIFIER', 'i');
}

if(!defined('COMMON_DATATABLE_CLASS_SORTED')) {
    define('COMMON_DATATABLE_CLASS_SORTED', 's');
}

if(!defined('COMMON_DATATABLE_NOT_APPLICABLE')) {
    define('COMMON_DATATABLE_NOT_APPLICABLE', '<span class="na">n/a</span>');
}

$int_max_colspan = 1000;

$bln_downloadable = false;
   
$int_headers = 0;
$arr_headers = $this->arr_headers;
$arr_columns = array_pop($arr_headers);

// use 'caption' if possible
$str_caption = isset($this->arr_properties['caption']) ? $this->arr_properties['caption'] : null;

$arr_sorting = isset($this->arr_properties['sorting']) ? $this->arr_properties['sorting'] : array();

$arr_groups = isset($this->arr_data['groups']) ? $this->arr_data['groups'] : array();

$groupRenderer = null;
if (isset($this->arr_options['group_renderer']) && ($this->arr_options['group_renderer'] instanceof Common_DataTable_GroupRenderer)) {
    $groupRenderer = $this->arr_options['group_renderer'];
}
?>
<div class="datatable">
<?php

echo '<table>';

//==============================================================================
// Columns
//==============================================================================

/*
echo '   <colgroup>' . "\n";

$int_column_index = 0;
foreach($arr_columns as $str_key => $mix_header) {
    
    $arr_header = is_array($mix_header) ? $mix_header : array('label' => $mix_header);    
    $arr_classes = isset($arr_header['class']) ? (array) $arr_header['class'] : array();

    if(in_array('number', $arr_classes)) {
        $i = array_search('number', $arr_classes);
        $arr_classes[$i] = COMMON_DATATABLE_CLASS_NUMBER;
    }
    
    $str_class = !empty($arr_classes) ? ' class="' . implode(' ', $arr_classes) . '"' : '';
    
    echo '      <col' . $str_class . ' rel="col:' . $int_column_index . '"></col>' . "\n";

    $int_column_index++; 
    
    if(is_array($mix_header)) {
        $arr_columns[$str_key]['class'] = $arr_classes;
    }
}
echo '   </colgroup>' . "\n";
*/

if(!empty($str_caption)) {
    echo '   <caption>' . $str_caption . '</caption>' . "\n";
}

//==============================================================================
// Headers
//==============================================================================

echo '   <thead>' . "\n";

foreach($arr_headers as $arr_header_row) {
    
    $str_css_class = ($int_headers == 0) ? 'rh' : 'rh-sub';
    echo '      <tr class="' . $str_css_class . '">' . "\n";
    foreach($arr_header_row as $str_key => $arr_header) {
        $str_label    = isset($arr_header['label']) ? $arr_header['label'] : $str_key;
        $int_children = isset($arr_header['children']) ? (int) $arr_header['children'] : 1;
        $str_span     = ($int_children > 1) ? ($int_children <= $int_max_colspan) ? ' colspan="' . $int_children . '"' : ' colspan="' . $int_max_colspan . '"' : '';
        
        $arr_classes = isset($arr_header['class_header']) ? (array) $arr_header['class_header'] : array();
        $str_class   = !empty($arr_classes) ? ' class="' . implode(' ', $arr_classes) . '"' : '';

        $str_sort_key = isset($arr_header['sort_source']) ? $arr_header['sort_source'] : $str_key;

        $str_label_escaped = $this->escape($str_label);

        if ($int_children <= $int_max_colspan &&
           isset($arr_header['source']) && !empty($str_url)) {

            $str_column_source = $arr_header['source'];
            if (
                isset($arr_columns[$str_column_source]['sortable']) &&
                ($arr_columns[$str_column_source]['sortable'] === true) &&
                !$bln_disable_sorting
            ) {
                
                $enm_sort_direction = 1;
                if(isset($arr_sorting[$str_column_source])) {

                    // if already sorted ascending, then make the link descending
                    if($arr_sorting[$str_column_source] == SORT_ASC) {
                        $enm_sort_direction = -1;
                    }
                } else if(isset($arr_columns[$str_column_source]['sort_first'])) {
                    $enm_sort_direction = ($arr_columns[$str_column_source]['sort_first'] == SORT_ASC) ? 1 : -1;
                }

                $str_sort_description = 'Click to sort this column in {order} order.';
                if($enm_sort_direction == 1) {
                    $str_sort_description = str_replace('{order}', 'ascending', $str_sort_description);
                } else if($enm_sort_direction == -1) {
                    $str_sort_description = str_replace('{order}', 'descending', $str_sort_description);
                }

                $str_label_escaped = '<a title="' . $str_sort_description . '" class="js_sort_link" href="' . $str_url. '?sort=' . $str_column_source . '&sort_dir=' . $enm_sort_direction . '">' . $str_label_escaped . '</a>';
            }
        }

        if ($int_children > $int_max_colspan) {
            while ($int_children > $int_max_colspan) {
                echo '<th' . $str_span . $str_class . '>' . $str_label_escaped . '</th>';
                $int_children -= $int_max_colspan;
            }
            if ($int_children > 0) {
                $str_span = ' colspan="' . $int_children . '"';
                echo '<th' . $str_span . $str_class . '>' . $str_label_escaped . '</th>';
            }
        }
        else {
            echo '<th' . $str_span . $str_class . '>' . $str_label_escaped . '</th>';
        }
    }
    echo  "\n" . '      </tr>' . "\n";
    $int_headers++;
}

//==============================================================================
// Columns
//==============================================================================

$int_column_index = 0;
$str_css_class = ($int_headers == 0) ? 'rh' : 'rh-sub';
echo '      <tr class="' . $str_css_class . ' columns">' . "\n";
foreach($arr_columns as $str_key => $mix_header) {
    
    $arr_header = (array) $mix_header;
    $str_label = $str_key;
    if(is_string($mix_header)) {
        $str_label = $mix_header;
    } else if(isset($arr_header['label'])) {
        $str_label = $arr_header['label'];
    }

    $str_sort_key = isset($arr_header['sort_source']) ? $arr_header['sort_source'] : $str_key;

    $arr_classes = isset($arr_header['class_header']) ? (array) $arr_header['class_header'] : array();
    
    $str_class_sorting = null;
    if(isset($arr_sorting[$str_sort_key])) {
        $str_class_sorting = 'sorting';
        if(count($arr_sorting) > 1) {
            $int_index = Utility_ArrayFunctions::index_of_key($arr_sorting, $str_sort_key);
            $int_index++;
            $str_class_sorting .= $int_index;
        }
        $str_class_sorting .= ($arr_sorting[$str_sort_key] == SORT_ASC) ? '_asc' : '_desc';
    }
    
    $str_class = !empty($arr_classes) ? ' class="' . implode(' ', $arr_classes) . '"' : '';

    $str_width_spacer = '';
    $str_width = '';
    if(isset($arr_header['width'])) {
        $str_width = ' style="width:' . $arr_header['width'] . ';"';
    } else if(isset($arr_header['width_spacer'])) {
        $str_width_spacer = '<div style="width: ' . $arr_header['width_spacer'] . '; height: 1px;"></div>';
    }
    
    $str_label_escaped = $this->escape($str_label);

    if(
        isset($arr_header['sortable']) &&
        ($arr_header['sortable'] === true) &&
        !empty($str_url) &&
        !$bln_disable_sorting
    ) {

        $enm_sort_direction = 1;
        if(isset($arr_sorting[$str_sort_key])) {

            // if already sorted ascending, then make the link descending
            if($arr_sorting[$str_sort_key] == SORT_ASC) {
                $enm_sort_direction = -1;
            }
        } else if(isset($arr_header['sort_first'])) {
            $enm_sort_direction = ($arr_header['sort_first'] == SORT_ASC) ? 1 : -1;
        }

        $str_sort_description = 'Click to sort this column in {order} order.';
        if($enm_sort_direction == 1) {
            $str_sort_description = str_replace('{order}', 'ascending', $str_sort_description);
        } else if($enm_sort_direction == -1) {
            $str_sort_description = str_replace('{order}', 'descending', $str_sort_description);
        }

        $str_label_escaped = '<a title="' . $str_sort_description . '" class="js_sort_link" href="' . $str_url. '?sort=' . $str_sort_key . '&sort_dir=' . $enm_sort_direction . '">' . $str_label_escaped . '</a>';
    }

    if(!empty($str_class_sorting)) {
        $str_label_escaped = '<span class="' . $str_class_sorting . '">' . $str_label_escaped . '</span>';
    }
    
    $str_rollover = null;
    if(isset($arr_header['rollover'])) {
        $str_rollover = '<span class="js-ro-content" style="display:none;z-index:-1000;">' . $arr_header['rollover'] . '</span>';
    }
    
    echo '<th' . $str_class . $str_width . ' rel="col:' . $int_column_index . '">' . $str_label_escaped . $str_rollover . $str_width_spacer . '</th>';
    
    $int_column_index++;
}
echo "\n" . '      </tr>' . "\n";
$int_headers++;

echo '   </thead>' . "\n";

//==============================================================================
// Body
//==============================================================================

echo '   <tbody>' . "\n";

$int_columns = count($arr_columns);

$arr_rows = $this->arr_data['rows'];
foreach($arr_rows as $str_group_key => $arr_group_rows) {

    $arr_group_meta = isset($arr_groups[$str_group_key])
        ? $arr_groups[$str_group_key]
        : array();

    if (!is_null($groupRenderer)) {

        echo $groupRenderer->render($str_group_key, $arr_group_meta, $int_columns, $this->arr_options);

    } else {

        $str_group_label = isset($arr_group_meta['label']) ? $arr_group_meta['label'] : null;
        $str_group_depth = isset($arr_group_meta['depth']) ? $arr_group_meta['depth'] : 1;

        if(!is_null($str_group_label)) {
            echo '      <tr class="rg rg-' . $str_group_depth . '">' . "\n";
            echo '          <td colspan="' . $int_columns . '">' . $this->escape($str_group_label) . '</td>' . "\n";
            echo '      </tr>' . "\n";
        }

    }

    if(isset($arr_group_meta['headers'])) {
        
        $i = 0;
        foreach($arr_group_meta['headers'] as $str_row_key => $arr_row) {
            Common_DataTable_View_Html::generateRow($i, $str_row_key, $arr_row, $arr_columns, array(
                'row_class' => 'rgh',
                'sorting' => $arr_sorting
            ));
            $i++;
        }
    
    }
    
    if(is_array($arr_group_rows) || ($arr_group_rows instanceof IteratorAggregate)) {

        $i = 0;
        foreach($arr_group_rows as $str_row_key => $arr_row) {
            Common_DataTable_View_Html::generateRow($i, $str_row_key, $arr_row, $arr_columns, array_merge($this->arr_options, array(
                'sorting' => $arr_sorting
            )));
            $i++;
        }

    }
    
    if(isset($arr_group_meta['footers'])) {
        
        $i = 0;
        foreach($arr_group_meta['footers'] as $str_row_key => $arr_row) {
            Common_DataTable_View_Html::generateRow($i, $str_row_key, $arr_row, $arr_columns, array(
                'row_class' => 'rgf',
                'sorting' => $arr_sorting
            ));
            $i++;
        }
    
    }

}
echo '   </tbody>' . "\n";

if(isset($this->arr_footers) && !empty($this->arr_footers)) {

    echo '   <tfoot>' . "\n";

    $i = 0;
    foreach($this->arr_footers as $arr_row) {
        
        $int_column_index = 0;
        
        echo '   <tr class="rf">' . "\n";
        foreach($arr_columns as $str_key => $mix_header) {
            
            $arr_header = is_string($mix_header) ? array('label' => $mix_header) : (array) $mix_header;
            
            $str_source_key = isset($arr_header['source']) ? $arr_header['source'] : $str_key;
            
            $mix_value = isset($arr_row[$str_source_key]) ? $arr_row[$str_source_key] : null;
            
            $arr_css_class = isset($arr_header['class']) ? (array) $arr_header['class'] : array();
            
            if(in_array(COMMON_DATATABLE_CLASS_NUMBER, $arr_css_class) && ($mix_value < 0)) {
                $arr_css_class[] = COMMON_DATATABLE_CLASS_NEGATIVE;
            }
            
            if(is_null($mix_value)) {
                
                $mix_value = COMMON_DATATABLE_NOT_APPLICABLE;
                
                if(isset($arr_header['default'])) {
                    $mix_value = $arr_header['default'];
                }
                
            } else {
                
                $mix_value = $this->escape($mix_value);
                
                $enm_format = null;
                $enm_format_type = 'normal';
                if(isset($arr_header['format_footer'])) {
                    $enm_format = $arr_header['format_footer'];
                    $enm_format_type = 'footer';
                } else if(isset($arr_header['format'])) {
                    $enm_format = $arr_header['format'];
                }
                
                $arr_format_options = array();
                if(($enm_format_type == 'footer') && isset($arr_header['format_footer_options'])) {
                    $arr_format_options = $arr_header['format_footer_options'];
                } else if(($enm_format_type == 'normal') && isset($arr_header['format_options'])) {
                    $arr_format_options = $arr_header['format_options'];
                }
                
                if(!is_null($enm_format)) {
                    
                    $mix_value = Utility_FormatFunctions::format_value($enm_format, $mix_value, $arr_row, $arr_format_options);
                }
            }
            
            $str_class = !empty($arr_css_class) ? 'class="' . implode(' ', $arr_css_class) . '" ' : '';
            
            echo '<td ' . $str_class . 'rel="col:' . $int_column_index . '">' . $mix_value . '</td>';
            
            $int_column_index++;
        }
        echo "\n" . '      </tr>' . "\n";
    
        $i++;
        
    }

    echo '   </tfoot>' . "\n";

}

echo '</table>' . "\n";

$str_persistance_id = isset($this->arr_meta['persistance_id']) ? $this->arr_meta['persistance_id'] : null;
if($bln_downloadable && !is_null($str_persistance_id)) {
?>
    <div class="downloader">
        Download as: <div class="download-strategy"><a href="<?php echo $this->baseUrl(); ?>/services/datatable/<?php echo $str_persistance_id . '/' . Common_DataTable_Exporter::EXPORT_CSV; ?>">CSV</a></div> | <div class="download-strategy"><a href="<?php echo $this->baseUrl(); ?>/services/datatable/<?php echo $str_persistance_id . '/' . Common_DataTable_Exporter::EXPORT_EXCEL; ?>">Excel</a></div>
    </div>
    <div class="close clear"></div>
<?php
}

if (isset($this->str_page_controls) && !empty($this->str_page_controls)) :
?>
<div class="after_datatable" id="js_after_datatable">
    <?php echo $this->str_page_controls ?>
</div>
<?php
endif;

$str_source = isset($this->arr_properties['source']) && !empty($this->arr_properties['source'])
    ? $this->arr_properties['source']
    : null;

if(!empty($str_source)) {
    echo '<div class="table-source">' . $this->escape($str_source) . '</div>';
}

$arr_notes = array();
if(isset($this->arr_meta['data_note']) && !empty($this->arr_meta['data_note'])) {
    $arr_notes = (array) $this->arr_meta['data_note'];
}
if(isset($this->arr_meta['notes']) && !empty($this->arr_meta['notes'])) {
    $arr_notes = (array) $this->arr_meta['notes'];
}

$int_start = $this->arr_data['offset'];
$int_count = $this->arr_data['count'];

if(!is_null($int_start)) {
    $int_end   = $int_start + $this->arr_data['size'];    
    $arr_notes[] = 'Displaying ' . ($int_start+1) . ' - ' . $int_end . ' of ' . $int_count . ' items';
} else {
    $arr_notes[] = 'Displaying ' . $int_count . ' items';
}

if(!empty($arr_notes)) {
    foreach($arr_notes as $str_note) {

        $str_note = $this->escape($str_note);

        echo '<div class="table-note">' . $str_note . '</div>';
    }
}
?>
</div>


